home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / hardware / adflib / adflibppc / lib / adf_hd.c < prev    next >
C/C++ Source or Header  |  1999-06-14  |  23KB  |  967 lines

  1. /*
  2.  *  ADF Library. (C) 1997-1998 Laurent Clevy
  3.  *
  4.  *  adf_hd.c
  5.  *
  6.  */
  7.  
  8.  
  9.  
  10. #include<stdio.h>
  11. #include<stdlib.h>
  12. #include<string.h>
  13.  
  14. #include"adf_str.h"
  15. #include"hd_blk.h"
  16. #include"adf_raw.h"
  17. #include"adf_hd.h"
  18. #include"adf_util.h"
  19. #include"adf_disk.h"
  20. #include"adf_nativ.h"
  21. #include"adf_dump.h"
  22. #include"adf_err.h"
  23.  
  24. #include"defendian.h"
  25.  
  26. extern struct Env adfEnv;
  27.  
  28. /*
  29.  * adfDevType
  30.  *
  31.  * returns the type of a device
  32.  * only based of the field 'dev->size'
  33.  */
  34. int adfDevType(struct Device* dev)
  35. {
  36.     if (dev->size==512*11*2*80)
  37.         return(DEVTYPE_FLOPDD);
  38.     else if (dev->size==512*22*2*80)
  39.         return(DEVTYPE_FLOPHD);
  40.     else if (dev->size>512*22*2*80)
  41.         return(DEVTYPE_HARDDISK);
  42.     else {
  43.         (*adfEnv.eFct)("adfDevType : unknown device type");
  44.         return(-1);
  45.     }
  46. }
  47.  
  48.  
  49. /*
  50.  * adfDeviceInfo
  51.  *
  52.  * display information about the device and its volumes
  53.  * for demonstration purpose only since the output is stdout !
  54.  *
  55.  * can be used before adfCreateVol() or adfMount()
  56.  */
  57. void adfDeviceInfo(struct Device *dev)
  58. {
  59.     int i;
  60.     
  61.     printf("Cylinders   = %ld\n",dev->cylinders);
  62.     printf("Heads       = %ld\n",dev->heads);
  63.     printf("Sectors/Cyl = %ld\n\n",dev->sectors);
  64.     if (!dev->isNativeDev)
  65.         printf("Dump device\n\n");
  66.     else
  67.         printf("Real device\n\n");
  68.     printf("Volumes     = %d\n\n",dev->nVol);
  69. /*
  70.     switch(dev->devType){
  71.     case DEVTYPE_FLOPDD:
  72.         printf("floppy dd\n"); break;
  73.     case DEVTYPE_FLOPHD:
  74.         printf("floppy hd\n"); break;
  75.     case DEVTYPE_HARDDISK:
  76.         printf("harddisk\n"); break;
  77.     case DEVTYPE_HARDFILE:
  78.         printf("hardfile\n"); break;
  79.     default:
  80.         printf("unknown devType!\n"); break;
  81.     }
  82. */
  83.  
  84.     for(i=0; i<dev->nVol; i++) {
  85.         if (dev->volList[i]->volName)
  86.             printf("%2d :  %7ld ->%7ld, \"%s\"", i,
  87.             dev->volList[i]->firstBlock,
  88.             dev->volList[i]->lastBlock,
  89.             dev->volList[i]->volName);
  90.         else
  91.             printf("%2d :  %7ld ->%7ld\n", i,
  92.             dev->volList[i]->firstBlock,
  93.             dev->volList[i]->lastBlock);
  94.         if (dev->volList[i]->mounted)
  95.             printf(", mounted");
  96.         putchar('\n');
  97.     }
  98. }
  99.  
  100.  
  101. /*
  102.  * adfFreeTmpVolList
  103.  *
  104.  */
  105. void adfFreeTmpVolList(struct List *root)
  106. {
  107.     struct List *cell;
  108.     struct Volume *vol;
  109.  
  110.     cell = root;
  111.     while(cell!=NULL) {
  112.         vol = (struct Volume *)cell->content;
  113.         if (vol->volName!=NULL)
  114.             free(vol->volName);  
  115.         cell = cell->next;
  116.     }
  117.     freeList(root);
  118.  
  119. }
  120.  
  121.  
  122. /*
  123.  * adfMountHdFile
  124.  *
  125.  */
  126. RETCODE adfMountHdFile(struct Device *dev)
  127. {
  128.     struct Volume* vol;
  129.     unsigned char buf[512];
  130.     long size;
  131.     BOOL found;
  132.  
  133.     dev->devType = DEVTYPE_HARDFILE;
  134.  
  135.     dev->volList = (struct Volume**)malloc(sizeof(struct Volume*));
  136.     if (!dev->volList) { 
  137.         (*adfEnv.eFct)("adfMountHdFile : malloc");
  138.         return RC_ERROR;
  139.     }
  140.  
  141.     vol=(struct Volume*)malloc(sizeof(struct Volume));
  142.     if (!vol) {
  143.         (*adfEnv.eFct)("adfMountHdFile : malloc");
  144.         return RC_ERROR;
  145.     }
  146.     dev->volList[0] = vol;
  147.     dev->nVol++;
  148.  
  149.     vol->volName=NULL;
  150.     
  151.     dev->cylinders = dev->size/512;
  152.     dev->heads = 1;
  153.     dev->sectors = 1;
  154.  
  155.     vol->firstBlock = 0;
  156.  
  157.     size = dev->size + 512-(dev->size%512);
  158. //printf("size=%ld\n",size);
  159.     vol->rootBlock = (size/512)/2;
  160. //printf("root=%ld\n",vol->rootBlock);
  161.     do {
  162.         adfReadDumpSector(dev, vol->rootBlock, 512, buf);
  163.         found = swapLong(buf)==T_HEADER && swapLong(buf+508)==ST_ROOT;
  164.         if (!found)
  165.             (vol->rootBlock)--;
  166.     }while (vol->rootBlock>1 && !found);
  167.  
  168.     if (vol->rootBlock==1) {
  169.         (*adfEnv.eFct)("adfMountHdFile : rootblock not found");
  170.         return RC_ERROR;
  171.     }
  172.     vol->lastBlock = vol->rootBlock*2 - 1 ;
  173.  
  174.     return RC_OK;
  175. }
  176.  
  177.  
  178. /*
  179.  * adfMountHd
  180.  *
  181.  * normal not used directly : called by adfMount()
  182.  *
  183.  * fills geometry fields and volumes list (dev->nVol and dev->volList[])
  184.  */
  185. RETCODE adfMountHd(struct Device *dev)
  186. {
  187.     struct bRDSKblock rdsk;
  188.     struct bPARTblock part;
  189.     struct bFSHDblock fshd;
  190.     struct bLSEGblock lseg;
  191.     long next;
  192.     struct List *vList, *listRoot;
  193.     int i;
  194.     struct Volume* vol;
  195.     int len;
  196.  
  197.     if (adfReadRDSKblock( dev, &rdsk )!=RC_OK)
  198.         return RC_ERROR;
  199.  
  200.     dev->cylinders = rdsk.cylinders;
  201.     dev->heads = rdsk.heads;
  202.     dev->sectors = rdsk.sectors;
  203.  
  204.     /* PART blocks */
  205.     listRoot = NULL;
  206.     next = rdsk.partitionList;
  207.     dev->nVol=0;
  208.     vList = NULL;
  209.     while( next!=-1 ) {
  210.         if (adfReadPARTblock( dev, next, &part )!=RC_OK) {
  211.             adfFreeTmpVolList(listRoot);
  212.             (*adfEnv.eFct)("adfMountHd : malloc");
  213.             return RC_ERROR;
  214.         }
  215.  
  216.         vol=(struct Volume*)malloc(sizeof(struct Volume));
  217.         if (!vol) {
  218.             adfFreeTmpVolList(listRoot);
  219.             (*adfEnv.eFct)("adfMountHd : malloc");
  220.             return RC_ERROR;
  221.         }
  222.         vol->volName=NULL;
  223.         dev->nVol++;
  224.  
  225.         vol->firstBlock = rdsk.cylBlocks * part.lowCyl;
  226.         vol->lastBlock = (part.highCyl+1)*rdsk.cylBlocks -1 ;
  227.         vol->rootBlock = (vol->lastBlock - vol->firstBlock+1)/2;
  228.  
  229.         len = min(31, part.nameLen);
  230.         vol->volName = (char*)malloc(len+1);
  231.         if (!vol->volName) { 
  232.             adfFreeTmpVolList(listRoot);
  233.             (*adfEnv.eFct)("adfMount : malloc");
  234.             return RC_ERROR;
  235.         }
  236.         memcpy(vol->volName,part.name,len);
  237.         vol->volName[len] = '\0';
  238.  
  239.         vol->mounted = FALSE;
  240.  
  241.         /* stores temporaly the volumes in a linked list */
  242.         if (listRoot==NULL)
  243.             vList = listRoot = newCell(NULL, (void*)vol);
  244.         else
  245.             vList = newCell(vList, (void*)vol);
  246.  
  247.         if (vList==NULL) {
  248.             adfFreeTmpVolList(listRoot);
  249.             (*adfEnv.eFct)("adfMount : newCell() malloc");
  250.             return RC_ERROR;
  251.         }
  252.  
  253.         next = part.next;
  254.     }
  255.  
  256.     /* stores the list in an array */
  257.     dev->volList = (struct Volume**)malloc(sizeof(struct Volume*) * dev->nVol);
  258.     if (!dev->volList) { 
  259.         adfFreeTmpVolList(listRoot);
  260.         (*adfEnv.eFct)("adfMount : unknown device type");
  261.         return RC_ERROR;
  262.     }
  263.     vList = listRoot;
  264.     for(i=0; i<dev->nVol; i++) {
  265.         dev->volList[i]=(struct Volume*)vList->content;
  266.         vList = vList->next;
  267.     }
  268.     freeList(listRoot);
  269.  
  270.     next = rdsk.fileSysHdrList;
  271.     while( next!=-1 ) {
  272.         if (adfReadFSHDblock( dev, next, &fshd )!=RC_OK) {
  273.             for(i=0;i<dev->nVol;i++) free(dev->volList[i]);
  274.             free(dev->volList);
  275.             (*adfEnv.eFct)("adfMount : adfReadFSHDblock");
  276.             return RC_ERROR;
  277.         }
  278.         next = fshd.next;
  279.     }
  280.  
  281.     next = fshd.segListBlock;
  282.     while( next!=-1 ) {
  283.         if (adfReadLSEGblock( dev, next, &lseg )!=RC_OK) {
  284.             (*adfEnv.wFct)("adfMount : adfReadLSEGblock");
  285.         }
  286.         next = lseg.next;
  287.     }
  288.  
  289.     return RC_OK;
  290. }
  291.  
  292.  
  293. /*
  294.  * adfMountFlop
  295.  *
  296.  * normaly not used directly, called directly by adfMount()
  297.  *
  298.  * use dev->devType to choose between DD and HD
  299.  * fills geometry and the volume list with one volume
  300.  */
  301. RETCODE adfMountFlop(struct Device* dev)
  302. {
  303.     struct Volume *vol;
  304.     
  305.     dev->cylinders = 80;
  306.     dev->heads = 2;
  307.     if (dev->devType==DEVTYPE_FLOPDD)
  308.         dev->sectors = 11;
  309.     else 
  310.         dev->sectors = 22;
  311.     
  312.     vol=(struct Volume*)malloc(sizeof(struct Volume));
  313.     if (!vol) { 
  314.         (*adfEnv.eFct)("adfMount : malloc");
  315.         return RC_ERROR;
  316.     }
  317.  
  318.     vol->volName = NULL;
  319.     vol->firstBlock = 0;
  320.     vol->lastBlock =(dev->cylinders * dev->heads * dev->sectors)-1;
  321.     vol->rootBlock = (vol->lastBlock+1 - vol->firstBlock)/2;
  322.  
  323.     dev->volList =(struct Volume**) malloc(sizeof(struct Volume*));
  324.     if (!dev->volList) {
  325.         free(vol);
  326.         (*adfEnv.eFct)("adfMount : malloc");
  327.         return RC_ERROR;
  328.     }
  329.     dev->volList[0] = vol;
  330.     dev->nVol = 1;
  331.  
  332. /*printf("root=%d\n",vol->rootBlock);        */
  333.     return RC_OK;
  334. }
  335.  
  336.  
  337. /*
  338.  * adfMountDev
  339.  *
  340.  * mount a dump file (.adf) or a real device (uses adf_nativ.c and .h)
  341.  *
  342.  * adfInitDevice() must fill dev->size !
  343.  */
  344. struct Device* adfMountDev( char* filename)
  345. {
  346.     struct Device* dev;
  347.     struct nativeFunctions *nFct;
  348.     RETCODE rc;
  349.     unsigned char buf[512];
  350.  
  351.     dev = (struct Device*)malloc(sizeof(struct Device));
  352.     if (!dev) {
  353.         (*adfEnv.eFct)("adfMountDev : malloc error");
  354.         return NULL;
  355.     }
  356.  
  357.     dev->readOnly = FALSE;
  358.  
  359.     /* switch between dump files and real devices */
  360.     nFct = adfEnv.nativeFct;
  361.     dev->isNativeDev = (*nFct->adfIsDevNative)(filename);
  362.     if (dev->isNativeDev)
  363.         rc = (*nFct->adfInitDevice)(dev, filename);
  364.     else
  365.         rc = adfInitDumpDevice(dev,filename);
  366.     if (rc!=RC_OK) {
  367.         free(dev); return(NULL);
  368.     }
  369.  
  370.     dev->devType = adfDevType(dev);
  371.  
  372.     switch( dev->devType ) {
  373.  
  374.     case DEVTYPE_FLOPDD:
  375.     case DEVTYPE_FLOPHD:
  376.         if (adfMountFlop(dev)!=RC_OK) {
  377.             free(dev); return NULL;
  378.         }
  379.         break;
  380.  
  381.     case DEVTYPE_HARDDISK:
  382.         /* to choose between hardfile or harddisk (real or dump) */
  383.         if (adfReadDumpSector(dev, 0, 512, buf)!=RC_OK) {
  384.             (*adfEnv.eFct)("adfMountDev : adfReadDumpSector failed");
  385.             free(dev); return NULL;
  386.         }
  387.  
  388.         /* a file with the first three bytes equal to 'DOS' */
  389.         if (!dev->isNativeDev && strncmp("DOS",buf,3)==0) {
  390.             if (adfMountHdFile(dev)!=RC_OK) {
  391.                 free(dev); return NULL;
  392.             }
  393.         }
  394.         else if (adfMountHd(dev)!=RC_OK) {
  395.             free(dev); return NULL;
  396.         }
  397.         break;
  398.  
  399.     default:
  400.         (*adfEnv.eFct)("adfMountDev : unknown device type");
  401.     }
  402.  
  403.     return dev;
  404. }
  405.  
  406.  
  407. /*
  408.  * adfCreateHdHeader
  409.  *
  410.  * create PARTIALLY the sectors of the header of one harddisk : can not be mounted
  411.  * back on a real Amiga ! It's because some device dependant values can't be guessed...
  412.  *
  413.  * do not use dev->volList[], but partList for partitions information : start and len are cylinders,
  414.  *  not blocks
  415.  * do not fill dev->volList[]
  416.  * called by adfCreateHd()
  417.  */
  418. RETCODE adfCreateHdHeader(struct Device* dev, int n, struct Partition** partList )
  419. {
  420.     int i;
  421.     struct bRDSKblock rdsk;
  422.     struct bPARTblock part;
  423.     struct bFSHDblock fshd;
  424.     struct bLSEGblock lseg;
  425.     SECTNUM j;
  426.     int len;
  427.  
  428.  
  429.     /* RDSK */ 
  430.  
  431.     memset((unsigned char*)&rdsk,0,sizeof(struct bRDSKblock));
  432.  
  433.     rdsk.rdbBlockLo = 0;
  434.     rdsk.rdbBlockHi = (dev->sectors*dev->heads*2)-1;
  435.     rdsk.loCylinder = 2;
  436.     rdsk.hiCylinder = dev->cylinders-1;
  437.     rdsk.cylBlocks = dev->sectors*dev->heads;
  438.  
  439.     rdsk.cylinders = dev->cylinders;
  440.     rdsk.sectors = dev->sectors;
  441.     rdsk.heads = dev->heads;
  442.     
  443.     rdsk.badBlockList = -1;
  444.     rdsk.partitionList = 1;
  445.     rdsk.fileSysHdrList = 1 + dev->nVol;
  446.     
  447.     if (adfWriteRDSKblock(dev, &rdsk)!=RC_OK)
  448.         return RC_ERROR;
  449.  
  450.     /* PART */
  451.  
  452.     j=1;
  453.     for(i=0; i<dev->nVol; i++) {
  454.         memset(&part, 0, sizeof(struct bPARTblock));
  455.  
  456.         if (i<dev->nVol-1)
  457.             part.next = j+1;
  458.         else
  459.             part.next = -1;
  460.  
  461.         len = min(MAXNAMELEN,strlen(partList[i]->volName));
  462.         part.nameLen = len;
  463.         strncpy(part.name, partList[i]->volName, len);
  464.  
  465.         part.surfaces = dev->heads;
  466.         part.blocksPerTrack = dev->sectors;
  467.         part.lowCyl = partList[i]->startCyl;
  468.         part.highCyl = partList[i]->startCyl + partList[i]->lenCyl -1;
  469.         strncpy(part.dosType, "DOS", 3);
  470.  
  471.         part.dosType[3] = partList[i]->volType & 0x01;
  472.             
  473.         if (adfWritePARTblock(dev, j, &part))
  474.             return RC_ERROR;
  475.         j++;
  476.     }
  477.  
  478.     /* FSHD */
  479.  
  480.     strncpy(fshd.dosType,"DOS",3);
  481.     fshd.dosType[3] = partList[0]->volType;
  482.     fshd.next = -1;
  483.     fshd.segListBlock = j+1;
  484.     if (adfWriteFSHDblock(dev, j, &fshd)!=RC_OK)
  485.         return RC_ERROR;
  486.     j++;
  487.     
  488.     /* LSEG */
  489.     lseg.next = -1;
  490.     if (adfWriteLSEGblock(dev, j, &lseg)!=RC_OK)
  491.         return RC_ERROR;
  492.  
  493.     return RC_OK;
  494. }
  495.  
  496.  
  497. /*
  498.  * adfCreateFlop
  499.  *
  500.  * create a filesystem on a floppy device
  501.  * fills dev->volList[]
  502.  */
  503. RETCODE adfCreateFlop(struct Device* dev, char* volName, int volType )
  504. {
  505.     if (dev==NULL) {
  506.         (*adfEnv.eFct)("adfCreateFlop : dev==NULL");
  507.         return RC_ERROR;
  508.     }
  509.     dev->volList =(struct Volume**) malloc(sizeof(struct Volume*));
  510.     if (!dev->volList) { 
  511.         (*adfEnv.eFct)("adfCreateFlop : unknown device type");
  512.         return RC_ERROR;
  513.     }
  514.     dev->volList[0] = adfCreateVol( dev, 0L, 80L, volName, volType );
  515.     if (dev->volList[0]==NULL) {
  516.         free(dev->volList);
  517.         return RC_ERROR;
  518.     }
  519.     dev->nVol = 1;
  520.     if (dev->sectors==11)
  521.         dev->devType=DEVTYPE_FLOPDD;
  522.     else
  523.         dev->devType=DEVTYPE_FLOPHD;
  524.  
  525.     return RC_OK;
  526. }
  527.  
  528.  
  529. /*
  530.  * adfCreateHd
  531.  *
  532.  * create a filesystem one an harddisk device (partitions==volumes, and the header)
  533.  *
  534.  * fills dev->volList[]
  535.  *
  536.  */
  537. RETCODE adfCreateHd(struct Device* dev, int n, struct Partition** partList )
  538. {
  539.     int i, j;
  540.  
  541. //struct Volume *vol;
  542.  
  543.     if (dev==NULL || partList==NULL || n<=0) {
  544.         (*adfEnv.eFct)("adfCreateHd : illegal parameter(s)");
  545.         return RC_ERROR;
  546.     }
  547.  
  548.     dev->volList =(struct Volume**) malloc(sizeof(struct Volume*)*n);
  549.     if (!dev->volList) {
  550.         (*adfEnv.eFct)("adfCreateFlop : malloc");
  551.         return RC_ERROR;
  552.     }
  553.     for(i=0; i<n; i++) {
  554.         dev->volList[i] = adfCreateVol( dev, 
  555.                     partList[i]->startCyl, 
  556.                     partList[i]->lenCyl, 
  557.                     partList[i]->volName, 
  558.                     partList[i]->volType );
  559.         if (dev->volList[i]==NULL) {
  560.            for(j=0; j<i; j++) {
  561.                free( dev->volList[i] );
  562. /* pas fini */
  563.            }
  564.            free(dev->volList);
  565.            (*adfEnv.eFct)("adfCreateHd : adfCreateVol() fails");
  566.         }
  567.     }
  568.     dev->nVol = n;
  569. /*
  570. vol=dev->volList[0];
  571. printf("0first=%ld last=%ld root=%ld\n",vol->firstBlock,
  572.  vol->lastBlock, vol->rootBlock);
  573. */
  574.  
  575.     if (adfCreateHdHeader(dev, n, partList )!=RC_OK)
  576.         return RC_ERROR;
  577.     return RC_OK;
  578. }
  579.  
  580.  
  581. /*
  582.  * adfUnMountDev
  583.  *
  584.  */
  585. void adfUnMountDev( struct Device* dev)
  586. {
  587.     int i;
  588.     struct nativeFunctions *nFct;
  589.  
  590.     if (dev==0)
  591.        return;
  592.  
  593.     for(i=0; i<dev->nVol; i++) {
  594.         free(dev->volList[i]->volName);
  595.         free(dev->volList[i]);
  596.     }
  597.     if (dev->nVol>0)
  598.         free(dev->volList);
  599.     dev->nVol = 0;
  600.  
  601.     nFct = adfEnv.nativeFct;
  602.     if (dev->isNativeDev)
  603.         (*nFct->adfReleaseDevice)(dev);
  604.     else
  605.         adfReleaseDumpDevice(dev);
  606.  
  607.     free(dev);
  608. }
  609.  
  610.  
  611.  
  612. /*
  613.  * ReadRDSKblock
  614.  *
  615.  */
  616.     RETCODE
  617. adfReadRDSKblock( struct Device* dev, struct bRDSKblock* blk )
  618. {
  619.  
  620.     UCHAR buf[256];
  621.     struct nativeFunctions *nFct;
  622.     RETCODE rc2;
  623.     RETCODE rc = RC_OK;
  624.     
  625.     nFct = adfEnv.nativeFct;
  626.     if (dev->isNativeDev)
  627.         rc2 =(*nFct->adfNativeReadSector)(dev, 0, 256, buf);
  628.     else
  629.         rc2 = adfReadDumpSector(dev, 0, 256, buf);
  630.  
  631.     if (rc2!=RC_OK)
  632.        return(RC_ERROR);
  633.  
  634.     memcpy(blk, buf, 256);
  635. #ifdef LITT_ENDIAN
  636.     /* big to little = 68000 to x86 */
  637.     swapEndian((unsigned char*)blk, SWBL_RDSK);
  638. #endif
  639.  
  640.     if ( strncmp(blk->id,"RDSK",4)!=0 ) {
  641.         (*adfEnv.eFct)("ReadRDSKblock : RDSK id not found");
  642.         return RC_ERROR;
  643.     }
  644.  
  645.     if ( blk->size != 64 )
  646.         (*adfEnv.wFct)("ReadRDSKBlock : size != 64\n");
  647.  
  648.     if ( blk->checksum != adfNormalSum(buf,8,256) ) {
  649.          (*adfEnv.wFct)("ReadRDSKBlock : incorrect checksum\n");
  650.          rc|=RC_BLOCKSUM;
  651.     }
  652.     
  653.     if ( blk->blockSize != 512 )
  654.          (*adfEnv.wFct)("ReadRDSKBlock : blockSize != 512\n");
  655.  
  656.     if ( blk->cylBlocks !=  blk->sectors*blk->heads )
  657.         (*adfEnv.wFct)( "ReadRDSKBlock : cylBlocks != sectors*heads");
  658.  
  659.     return rc;
  660. }
  661.  
  662.  
  663. /*
  664.  * adfWriteRDSKblock
  665.  *
  666.  */
  667.     RETCODE
  668. adfWriteRDSKblock(struct Device *dev, struct bRDSKblock* rdsk)
  669. {
  670.     unsigned char buf[LOGICAL_BLOCK_SIZE];
  671.     unsigned long newSum;
  672.     struct nativeFunctions *nFct;
  673.     RETCODE rc2, rc = RC_OK;
  674.  
  675.     if (dev->readOnly) {
  676.         (*adfEnv.wFct)("adfWriteRDSKblock : can't write block, read only device");
  677.         return RC_ERROR;
  678.     }
  679.  
  680.     memset(buf,0,LOGICAL_BLOCK_SIZE);
  681.  
  682.     strncpy(rdsk->id,"RDSK",4);
  683.     rdsk->size = sizeof(struct bRDSKblock)/sizeof(long);
  684.     rdsk->blockSize = LOGICAL_BLOCK_SIZE;
  685.     rdsk->badBlockList = -1;
  686.  
  687.     strncpy(rdsk->diskVendor,"ADFlib  ",8);
  688.     strncpy(rdsk->diskProduct,"harddisk.adf    ",16);
  689.     strncpy(rdsk->diskRevision,"v1.0",4);
  690.  
  691.     memcpy(buf, rdsk, sizeof(struct bRDSKblock));
  692. #ifdef LITT_ENDIAN
  693.     swapEndian(buf, SWBL_RDSK);
  694. #endif
  695.  
  696.     newSum = adfNormalSum(buf, 8, LOGICAL_BLOCK_SIZE);
  697.     swLong(buf+8, newSum);
  698.  
  699.     nFct = adfEnv.nativeFct;
  700.     if (dev->isNativeDev)
  701.         rc2=(*nFct->adfNativeWriteSector)(dev, 0, LOGICAL_BLOCK_SIZE, buf);
  702.     else
  703.         rc2=adfWriteDumpSector(dev, 0, LOGICAL_BLOCK_SIZE, buf);
  704.  
  705.     if (rc2!=RC_OK)
  706.        return RC_ERROR;
  707.  
  708.     return rc;
  709. }
  710.  
  711.  
  712. /*
  713.  * ReadPARTblock
  714.  *
  715.  */
  716.     RETCODE
  717. adfReadPARTblock( struct Device* dev, long nSect, struct bPARTblock* blk )
  718. {
  719.     UCHAR buf[ sizeof(struct bPARTblock) ];
  720.     struct nativeFunctions *nFct;
  721.     RETCODE rc2, rc = RC_OK;
  722.     
  723.     nFct = adfEnv.nativeFct;
  724.     if (dev->isNativeDev)
  725.         rc2=(*nFct->adfNativeReadSector)(dev, nSect, sizeof(struct bPARTblock), buf);
  726.     else
  727.         rc2=adfReadDumpSector(dev, nSect, sizeof(struct bPARTblock), buf);
  728.  
  729.     if (rc2!=RC_OK)
  730.        return RC_ERROR;
  731.  
  732.     memcpy(blk, buf, sizeof(struct bPARTblock));
  733. #ifdef LITT_ENDIAN
  734.     /* big to little = 68000 to x86 */
  735.     swapEndian((unsigned char*)blk, SWBL_PART);
  736. #endif
  737.  
  738.     if ( strncmp(blk->id,"PART",4)!=0 ) {
  739.         (*adfEnv.eFct)("ReadPARTblock : PART id not found");
  740.         return RC_ERROR;
  741.     }
  742.  
  743.     if ( blk->size != 64 )
  744.         (*adfEnv.wFct)("ReadPARTBlock : size != 64");
  745.  
  746.     if ( blk->checksum != adfNormalSum(buf,8,256) )
  747.         (*adfEnv.wFct)( "ReadPARTBlock : incorrect checksum");
  748.  
  749.     return rc;
  750. }
  751.  
  752.  
  753. /*
  754.  * adfWritePARTblock
  755.  *
  756.  */
  757.     RETCODE
  758. adfWritePARTblock(struct Device *dev, long nSect, struct bPARTblock* part)
  759. {
  760.     unsigned char buf[LOGICAL_BLOCK_SIZE];
  761.     unsigned long newSum;
  762.     struct nativeFunctions *nFct;
  763.     RETCODE rc2, rc = RC_OK;
  764.     
  765.     if (dev->readOnly) {
  766.         (*adfEnv.wFct)("adfWritePARTblock : can't write block, read only device");
  767.         return RC_ERROR;
  768.     }
  769.  
  770.     memset(buf,0,LOGICAL_BLOCK_SIZE);
  771.  
  772.     strncpy(part->id,"PART",4);
  773.     part->size = sizeof(struct bPARTblock)/sizeof(long);
  774.     part->blockSize = LOGICAL_BLOCK_SIZE;
  775.     part->vectorSize = 16;
  776.     part->blockSize = 128;
  777.     part->sectorsPerBlock = 1;
  778.     part->dosReserved = 2;
  779.  
  780.     memcpy(buf, part, sizeof(struct bPARTblock));
  781. #ifdef LITT_ENDIAN
  782.     swapEndian(buf, SWBL_PART);
  783. #endif
  784.  
  785.     newSum = adfNormalSum(buf, 8, LOGICAL_BLOCK_SIZE);
  786.     swLong(buf+8, newSum);
  787. //    *(long*)(buf+8) = swapLong((unsigned char*)&newSum);
  788.  
  789.     nFct = adfEnv.nativeFct;
  790.     if (dev->isNativeDev)
  791.         rc2=(*nFct->adfNativeWriteSector)(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
  792.     else
  793.         rc2=adfWriteDumpSector(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
  794.     if (rc2!=RC_OK)
  795.         return RC_ERROR;
  796.  
  797.     return rc;
  798. }
  799.  
  800. /*
  801.  * ReadFSHDblock
  802.  *
  803.  */
  804.     RETCODE
  805. adfReadFSHDblock( struct Device* dev, long nSect, struct bFSHDblock* blk)
  806. {
  807.     UCHAR buf[sizeof(struct bFSHDblock)];
  808.     struct nativeFunctions *nFct;
  809.     RETCODE rc;
  810.     
  811.     nFct = adfEnv.nativeFct;
  812.     if (dev->isNativeDev)
  813.         rc = (*nFct->adfNativeReadSector)(dev, nSect, sizeof(struct bFSHDblock), buf);
  814.     else
  815.         rc = adfReadDumpSector(dev, nSect, sizeof(struct bFSHDblock), buf);
  816.     if (rc!=RC_OK)
  817.         return RC_ERROR;
  818.         
  819.     memcpy(blk, buf, sizeof(struct bFSHDblock));
  820. #ifdef LITT_ENDIAN
  821.     /* big to little = 68000 to x86 */
  822.     swapEndian((unsigned char*)blk, SWBL_FSHD);
  823. #endif
  824.  
  825.     if ( strncmp(blk->id,"FSHD",4)!=0 ) {
  826.         (*adfEnv.eFct)("ReadFSHDblock : FSHD id not found");
  827.         return RC_ERROR;
  828.     }
  829.  
  830.     if ( blk->size != 64 )
  831.          (*adfEnv.wFct)("ReadFSHDblock : size != 64");
  832.  
  833.     if ( blk->checksum != adfNormalSum(buf,8,256) )
  834.         (*adfEnv.wFct)( "ReadFSHDblock : incorrect checksum");
  835.  
  836.     return RC_OK;
  837. }
  838.  
  839.  
  840. /*
  841.  *  adfWriteFSHDblock
  842.  *
  843.  */
  844.     RETCODE
  845. adfWriteFSHDblock(struct Device *dev, long nSect, struct bFSHDblock* fshd)
  846. {
  847.     unsigned char buf[LOGICAL_BLOCK_SIZE];
  848.     unsigned long newSum;
  849.     struct nativeFunctions *nFct;
  850.     RETCODE rc = RC_OK;
  851.  
  852.     if (dev->readOnly) {
  853.         (*adfEnv.wFct)("adfWriteFSHDblock : can't write block, read only device");
  854.         return RC_ERROR;
  855.     }
  856.  
  857.     memset(buf,0,LOGICAL_BLOCK_SIZE);
  858.  
  859.     strncpy(fshd->id,"FSHD",4);
  860.     fshd->size = sizeof(struct bFSHDblock)/sizeof(long);
  861.  
  862.     memcpy(buf, fshd, sizeof(struct bFSHDblock));
  863. #ifdef LITT_ENDIAN
  864.     swapEndian(buf, SWBL_FSHD);
  865. #endif
  866.  
  867.     newSum = adfNormalSum(buf, 8, LOGICAL_BLOCK_SIZE);
  868.     swLong(buf+8, newSum);
  869. //    *(long*)(buf+8) = swapLong((unsigned char*)&newSum);
  870.  
  871.     nFct = adfEnv.nativeFct;
  872.     if (dev->isNativeDev)
  873.         rc=(*nFct->adfNativeWriteSector)(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
  874.     else
  875.         rc=adfWriteDumpSector(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
  876.     if (rc!=RC_OK)
  877.         return RC_ERROR;
  878.  
  879.     return RC_OK;
  880. }
  881.  
  882.  
  883. /*
  884.  * ReadLSEGblock
  885.  *
  886.  */
  887.    RETCODE
  888. adfReadLSEGblock(struct Device* dev, long nSect, struct bLSEGblock* blk)
  889. {
  890.     UCHAR buf[sizeof(struct bLSEGblock)];
  891.     struct nativeFunctions *nFct;
  892.     RETCODE rc;
  893.     
  894.     nFct = adfEnv.nativeFct;
  895.     if (dev->isNativeDev)
  896.         rc=(*nFct->adfNativeReadSector)(dev, nSect, sizeof(struct bLSEGblock), buf);
  897.     else
  898.         rc=adfReadDumpSector(dev, nSect, sizeof(struct bLSEGblock), buf);
  899.     if (rc!=RC_OK)
  900.         return RC_ERROR;
  901.         
  902.     memcpy(blk, buf, sizeof(struct bLSEGblock));
  903. #ifdef LITT_ENDIAN
  904.     /* big to little = 68000 to x86 */
  905.     swapEndian((unsigned char*)blk, SWBL_LSEG);
  906. #endif
  907.  
  908.     if ( strncmp(blk->id,"LSEG",4)!=0 ) {
  909.         (*adfEnv.eFct)("ReadLSEGblock : LSEG id not found");
  910.         return RC_ERROR;
  911.     }
  912.  
  913.     if ( blk->checksum != adfNormalSum(buf,8,sizeof(struct bLSEGblock)) )
  914.         (*adfEnv.wFct)("ReadLSEGBlock : incorrect checksum");
  915.  
  916.     if ( blk->next!=-1 && blk->size != 128 )
  917.         (*adfEnv.wFct)("ReadLSEGBlock : size != 128");
  918.  
  919.     return RC_OK;
  920. }
  921.  
  922.  
  923. /*
  924.  * adfWriteLSEGblock
  925.  *
  926.  */
  927.     RETCODE
  928. adfWriteLSEGblock(struct Device *dev, long nSect, struct bLSEGblock* lseg)
  929. {
  930.     unsigned char buf[LOGICAL_BLOCK_SIZE];
  931.     unsigned long newSum;
  932.     struct nativeFunctions *nFct;
  933.     RETCODE rc;
  934.  
  935.     if (dev->readOnly) {
  936.         (*adfEnv.wFct)("adfWriteLSEGblock : can't write block, read only device");
  937.         return RC_ERROR;
  938.     }
  939.  
  940.     memset(buf,0,LOGICAL_BLOCK_SIZE);
  941.  
  942.     strncpy(lseg->id,"LSEG",4);
  943.     lseg->size = sizeof(struct bLSEGblock)/sizeof(long);
  944.  
  945.     memcpy(buf, lseg, sizeof(struct bLSEGblock));
  946. #ifdef LITT_ENDIAN
  947.     swapEndian(buf, SWBL_LSEG);
  948. #endif
  949.  
  950.     newSum = adfNormalSum(buf, 8, LOGICAL_BLOCK_SIZE);
  951.     swLong(buf+8,newSum);
  952. //    *(long*)(buf+8) = swapLong((unsigned char*)&newSum);
  953.  
  954.     nFct = adfEnv.nativeFct;
  955.     if (dev->isNativeDev)
  956.         rc=(*nFct->adfNativeWriteSector)(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
  957.     else
  958.         rc=adfWriteDumpSector(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
  959.  
  960.     if (rc!=RC_OK)
  961.         return RC_ERROR;
  962.  
  963.     return RC_OK;
  964. }
  965.  
  966. /*##########################################################################*/
  967.